package main

import (
	"fmt"
	"github.com/spf13/viper"
	"net/http"
	"net/http/httputil"
	"net/url"
)

// 配置文件对象
var _config *Config

type Config struct {
	Target []Target `yaml:"target" json:"target"`
	Enter  Enter    `yaml:"enter" json:"enter"`
}

type Target struct {
	Name string `yaml:"name" json:"name"`
	Url  string `yaml:"url" json:"url"`
}

type Enter struct {
	Port int `yaml:"port" json:"port"`
}

// LoadConfig 加载配置文件
func LoadConfig() {
	//导入配置文件
	viper.SetConfigType("yaml")
	viper.SetConfigFile("./config.yml")
	//读取配置文件
	err := viper.ReadInConfig()
	if err != nil {
		fmt.Println(err.Error())
	}

	//将配置文件读到结构体中
	err = viper.Unmarshal(&_config)
	if err != nil {
		fmt.Println(err.Error())
	}

}

func PrintConfigProxy() {
	// 打印配置路径
	fmt.Println("当前配置路径:")
	for i, t := range _config.Target {
		fmt.Println(i+1, ":")
		fmt.Println(fmt.Sprintf("http://localhost:%d/%s => http://%s/%s", _config.Enter.Port, t.Name, t.Url, t.Name))
	}
}

func main() {
	LoadConfig()
	PrintConfigProxy()
	for _, targer := range _config.Target {
		turl := targer.Url
		var tName string
		if targer.Name == "" {
			tName = "/" + targer.Name
		} else {
			tName = "/" + targer.Name + "/"
		}

		go func() {
			http.HandleFunc(tName, func(w http.ResponseWriter, r *http.Request) {
				urlStr := fmt.Sprintf("http://%s", turl)
				u, _ := url.Parse(urlStr)
				proxy := httputil.NewSingleHostReverseProxy(u)
				proxy.ServeHTTP(w, r)
			})
		}()
	}

	enterPort := fmt.Sprintf(":%d", _config.Enter.Port)
	err := http.ListenAndServe(enterPort, nil)

	if err != nil {
		fmt.Println("HTTP server failed err :", err)
		return
	}
}
